

import 'package:reabampos/src/reabam/operation/bean/api_download_db_file_url.dart';
import 'package:reabampos/src/reabam/operation/bean/api_upload_order_task.dart';
import 'package:reabampos/src/reabam/operation/bean/base/rb_request.dart';
import 'package:reabampos/src/reabam/operation/bean/base/rb_response.dart';
import 'package:reabampos/src/reabam/operation/bean/bean_goodtype.dart';
import 'package:reabampos/src/reabam/operation/bean/bean_paytype.dart';
import 'package:reabampos/src/reabam/operation/bean/bean_retry_order.dart';
import 'package:reabampos/src/reabam/operation/bean/check_app_update/Request_check_app_update.dart';
import 'package:reabampos/src/reabam/operation/bean/kuaimai/km_base_request.dart';
import 'package:reabampos/src/reabam/operation/bean/login/request_login.dart';
import 'package:reabampos/src/reabam/operation/bean/login/request_user_info.dart';
import 'package:reabampos/src/reabam/operation/bean/socket/Request_server_ip_list.dart';
import 'package:reabampos/src/reabam/operation/bean/socket/Request_update_serversocket.dart';
import 'package:reabampos/src/reabam/operation/rb_config.dart';
import 'package:reabampos/src/reabam/operation/rb_enum.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_aliyun_log.dart';
import 'package:xsdk_flutter/xsdk/xsdk_flutter_package.dart';

import 'bean/barcode_rule/Response_barcode_rule.dart';
import 'bean/upload_device_setting_info/request_upload_device_setting_info.dart';

typedef RBApiCallbackSucceed = void Function(Map<String,dynamic> responseMap,Map<String,dynamic> headers_response);//headers_response: Map<String, List<String>>
typedef RBApiCallbackSucceedT<T> = void Function(T response,Map<String,dynamic> responseMap,Map<String,dynamic> headers_response);//headers_response: Map<String, List<String>>

abstract class RBBaseApi{

  static Map<String,dynamic>? _getHeaders(){
    Map<String,dynamic> map = {};

    //旧认证
    // String sysNo=XSharePreferencesUtils.getString(RBConfigs.SP_sysNo);
    // if('take_order_hd'==sysNo){
    //   //接单端需要添加Authorization,否则tokenId过期,其他端不能添加Authorization,否则也会tokenId过期
    //   String tokenId = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    //   map['Authorization']='Bearer $tokenId';
    //   return map;
    // }

    //
    String tokenId = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    String group_id = XSharePreferencesUtils.getString(RBConfigs.SP_groupId);
    String company_id = XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    String user_id = XSharePreferencesUtils.getString(RBConfigs.SP_userId);
    map['group_id']=group_id;
    map['company_id']=company_id;
    map['user_id']= user_id;
    map['version']= RBConfigs.versionName;
    map['Authorization']='Bearer $tokenId';

    return map;
  }

  //处理电子秤结果
  static double? handleWeigherResultToDouble(String brand, String result){

    try{
      //XLogUtils.printLog('---usb电子秤result=$result');

      if('顶尖'==brand){
        //S  0,065KGv

        if(result.contains(',') && result.contains('KG')){
          int index1=result.indexOf(',');
          int index2=result.indexOf('KG');
          String rStatus=result.substring(2,3);
          String rZhengshu=result.substring(5,index1);
          String rXiaoshu=result.substring(index1+1,index2);

          //XLogUtils.printLog('---顶尖,状态:$rStatus, 整数部分:$rZhengshu, 小数部分:$rXiaoshu');

          double zs=XNumberUtils.string2double(rZhengshu)??0;
          double xs=(XNumberUtils.string2double(rXiaoshu)??0)/1000;

          return zs+xs;
        }

      }else if('大华'==brand){
        //0510
        if(result.length>=4){
          int length=result.length;
          String rZhengshu=result.substring(0,length-3);
          String rXiaoshu=result.substring(length-3,length);

          //XLogUtils.printLog('---大华,整数部分:$rZhengshu, 小数部分:$rXiaoshu');

          double zs=XNumberUtils.string2double(rZhengshu)??0;
          double xs=(XNumberUtils.string2double(rXiaoshu)??0)/1000;

          return zs+xs;
        }
      }
    }catch(e){
      //
    }

    return null;
  }

  static void requestApi_async(
      {
        required String url,
        String? requestJson,
        Map<String,dynamic>? requestMap,
        bool disableRetry=true,//默认关闭自动重试
        Duration? receiveTimeout,
        Map<String,dynamic>? headers,
        required RBApiCallbackSucceed succeed,
        required XHttpCallbackFailed failed,
      }
      ){

    if(requestMap!=null){
      requestMap['tokenId']=XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    }

    XHttpUtils.request_async(
        url: url,
        disableRetry:disableRetry,
        receiveTimeout:receiveTimeout,
        headers: headers??_getHeaders(),
        dataJson: requestMap!=null?XJsonUtils.obj2Json(requestMap):requestJson,
        succeed: (String result,Map<String,dynamic> headersResponse){
          RBBaseResponse response=RBBaseResponse.fromJson(XJsonUtils.json2Map(result));
          String? code = response.code;
          String? message = response.msg;
          dynamic ResultInt = response.ResultInt;
          String? ResultString = response.ResultString;

          //XLogUtils.printLog('---response.code=${response.code}');

          if(response.code!=null){
            if(code=="200") {
              succeed(XJsonUtils.json2Map(result),headersResponse);
            }else{
              failed(code??'-1',message??'request failed!');

              if(code=="8888" || code=="9999"){

                //自助收银
                if(RBConfigs.versionType==VersionType.officialSelfServiceVersion
                    || RBConfigs.versionType==VersionType.testSelfServiceVersion){

                  XSharePreferencesUtils.saveString(RBConfigs.SP_tokenId,'');
                  //
                  XNotifyStateChangeUtils.notifyStateChange(
                      action: RBConfigs.Notify_Global_Handler,
                      key: 'backToLoginPage',
                      value: ''
                  );

                }

              }

            }

          }else{
            if(ResultInt!=null && '$ResultInt' == '0') {
              succeed(XJsonUtils.json2Map(result),headersResponse);
            }else{
              failed('$ResultInt',ResultString??'request failed!');

              if(code=="8888" || code=="9999"){
                //自助收银
                if(RBConfigs.versionType==VersionType.officialSelfServiceVersion
                    || RBConfigs.versionType==VersionType.testSelfServiceVersion){

                  XSharePreferencesUtils.saveString(RBConfigs.SP_tokenId,'');
                  //
                  XNotifyStateChangeUtils.notifyStateChange(
                      action: RBConfigs.Notify_Global_Handler,
                      key: 'backToLoginPage',
                      value: ''
                  );

                }

              }

            }
          }
        },
        failed:failed
    );

  }

  static Future<Map<String,dynamic>?> requestApi_sync(
      {
        required String url,
        required String requestJson,
      }
      ) async{

    String result=await XHttpUtils.request_sync(
        url: url,
        headers: _getHeaders(),
        dataJson: requestJson
    );

    if(XStringUtils.isEmpty(result)){
      return null;
    }

    RBBaseResponse response=RBBaseResponse.fromJson(XJsonUtils.json2Map(result));
    String? code = response.code;
    String? message = response.msg;
    dynamic ResultInt = response.ResultInt;
    String? ResultString = response.ResultString;

    if(response.code!=null){
      if(code=="200") {
        return XJsonUtils.json2Map(result);
      }else{
        return null;
      }
    }else{
      if(ResultInt!=null && '$ResultInt'== '0') {
        return XJsonUtils.json2Map(result);
      }else{
        return null;
      }
    }
  }


  static void login(
      {
        required String mobile,
        required String loginWord,
        required String appVersion,
        String? clientVersion,
        required String jpushRegId,
        required String appType,
        required String loginType,
        String? groupId,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXApiUrl()}/api/reabam-manage-login/user/login";
    //
    LoginRequest request=LoginRequest(
      mobile,
      loginWord,
      appVersion,
      clientVersion,
      jpushRegId,
      appType,
      loginType,
      groupId,
    );
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        headers: {},
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headers_response){
          succeed(null,responseMap,headers_response);
        }
    );

  }


  //用户信息
  static void getUserAuthStatus(
      {
        required RBApiCallbackSucceedT<LoginInfoResponse> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXApiUrl()}/api/reabam-manage/app/Common/GetUserAuthStatus";
    //
    requestApi_async(
        url:url,
        requestMap:{},
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headers_response){
          LoginInfoResponse response=LoginInfoResponse.fromJson(responseMap);
          succeed(response,responseMap,headers_response);
        }
    );
  }



  //////////////////////////////////////////////////

  //快麦处理
  static void requestApi_km(
      {
        required String url,
        required String requestJson,
        required RBApiCallbackSucceed succeed,
        required XHttpCallbackFailed failed,
      }
      ){

    XHttpUtils.request_async(
        url: url,
        headers: null,
        dataJson: requestJson,
        succeed: (String result,Map<String,dynamic> headersResponse){
          //BaseKMResponse response=BaseKMResponse.fromJson(XJsonUtils.json2Map(result));
          Map<String,dynamic> response=XJsonUtils.json2Map(result);

          bool? status = response['status'];
          String? message = response['message'];
          if(status==true) {
            succeed(response,headersResponse);
          }else{
            failed('-1',message??'request failed!');
          }
        },
        failed:failed
    );

  }

  static String getXApiUrl(){
    return RBConfigs.apiUrl;
  }

  static String getXServerUrl(){
    return XSharePreferencesUtils.getString(RBConfigs.SP_serverAddress);
  }
  static String getXServerUrl2(){
    return XSharePreferencesUtils.getString(RBConfigs.SP_zuulServerAddress);
  }

  ////////////////////////////////////////////////////////////

  //检查版本升级
  static void checkAppVersionUpdate(
      {
        required String appCode,
        required RBApiCallbackSucceedT<ResponseCheckAppUpdate> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/om/app/checkAppVersion";
    //
    RequestCheckAppUpdate request=RequestCheckAppUpdate(appCode,'${RBConfigs.version}');
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          ResponseCheckAppUpdate response=ResponseCheckAppUpdate.fromJson(responseMap);
          succeed(response,responseMap,headersResponse);
        }
    );

  }


  static void getShopCartDetail(
      {
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-shoppingcart-front/app/shopCart/pos/getShopCartDetail";
    //
    Map<String,dynamic> requestMap={};
    requestMap['companyId']=XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    requestMap['userId']=XSharePreferencesUtils.getString(RBConfigs.SP_userId);

    //
    requestApi_async(
        url:url,
        requestMap:requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }

  //门店列表
  static void getStaffStoreList(
      {
        required String? sword,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/reabam-manage/staff/comp/login/list";
    //
    Map<String,dynamic> requestMap={};
    requestMap['sword']=sword;
    requestMap['userId']=XSharePreferencesUtils.getString(RBConfigs.SP_userId);
    requestMap['companyId']=XSharePreferencesUtils.getString(RBConfigs.SP_companyId);

    //
    requestApi_async(
        url:url,
        requestMap:requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }


  //切换品牌/门店
  static void changePinPaiShangOrCompany(
      {
        required String? groupId,
        required String? companyId,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXApiUrl()}/api/reabam-manage-login/user/change/login";
    //
    Map<String,dynamic> requestMap={};
    requestMap['groupId']=groupId;
    requestMap['companyId']=companyId;
    requestMap['userId']=XSharePreferencesUtils.getString(RBConfigs.SP_userId);

    requestApi_async(
        url:url,
        requestMap: requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headers_response){
          succeed(null,responseMap,headers_response);
        }
    );
  }
  //会员搜索
  static void searchMemberList(
      {
        required String? searchWord,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/reabam-retail-fast/app/Business/Member/Search";
    //
    Map<String,dynamic> requestMap={};
    requestMap['orderField']='date';
    requestMap['orderSort']='desc';
    requestMap['filterType']=2;
    requestMap['entrance']=1;
    requestMap['pageIndex']=1;
    requestMap['pageSize']=20;
    requestMap['searchWord']=searchWord;

    requestApi_async(
        url:url,
        requestMap: requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headers_response){
          succeed(null,responseMap,headers_response);
        }
    );
  }

  static void getStaffList(
      {
        required int pageIndex,
        required String? sword,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-order-fast/orderfast/app/Business/Staff/List";
    //
    Map<String,dynamic> requestMap={};
    requestMap['sword']=sword;
    requestMap['pageIndex']=pageIndex;
    requestMap['pageSize']=20;

    //
    requestApi_async(
        url:url,
        requestMap:requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }
  static void updateStaff(
      {
        required String? staffId,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-shoppingcart-front/app/shopping/cart/updateItemStaff";
    //
    Map<String,dynamic> requestMap={};
    requestMap['companyId']=XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    requestMap['userId']=XSharePreferencesUtils.getString(RBConfigs.SP_userId);
    requestMap['staffId']=staffId;

    //
    requestApi_async(
        url:url,
        requestMap:requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }


  //商品分类
  static void goodTypeList(
      {
        required String optType,
        required String filterType,
        required RBApiCallbackSucceedT<GoodTypeResponse> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/product-front/app/Business/Order/ProductTypes";

    //
    GoodTypeRequest request=GoodTypeRequest(optType:optType,filterType:filterType);
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          GoodTypeResponse response=GoodTypeResponse.fromJson(responseMap);
          succeed(response,responseMap,headersResponse);
        }
    );

  }

  //支付方式
  static void payList(
      {
        String? equipmentIdentity,
        required RBApiCallbackSucceedT<PayTypeResponse> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-pay-front/app/Common/AppCode/PayType";
    //
    PayTypeRequest request=PayTypeRequest(equipmentIdentity:equipmentIdentity);
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          PayTypeResponse response=PayTypeResponse.fromJson(responseMap);
          succeed(response,responseMap,headersResponse);
        }
    );

  }

  //刷新订单是否已追平接口
  static Future<Response_retry_pos_order?> retryPosOrder(
      {
        required List<String> fastOrderNos,
        required String groupId,
      }
      ) async{
    //
    String url = "${getXServerUrl2()}/retail-order-front/fast/order/task/push/retry/batch/pos";
    //
    Request_retry_pos_order request=Request_retry_pos_order();
    request.fastOrderNos=fastOrderNos;
    request.groupId=groupId;
    //
    Map<String,dynamic>? responseMap= await requestApi_sync(
        url:url,
        requestJson:XJsonUtils.obj2Json(request)
    );

    if(responseMap!=null){
      Response_retry_pos_order response=Response_retry_pos_order.fromJson(responseMap);
      return response;
    }

    return null;

  }


  //检测订单是否已追平
  static Future<Response_check_order?> checkOrderBusinessStatus(
      {
        required List<String> fastOrderNos,
      }
      ) async{
    //
    String url = "${getXServerUrl2()}/retail-order-front/fast/order/task/push/checker";
    //
    Request_retry_pos_order request=Request_retry_pos_order();
    request.fastOrderNos=fastOrderNos;
    //
    Map<String,dynamic>? responseMap= await requestApi_sync(
        url:url,
        requestJson:XJsonUtils.obj2Json(request)
    );

    if(responseMap!=null){
      Response_check_order response=Response_check_order.fromJson(responseMap);
      return response;
    }

    return null;

  }

  //上传任务
  static Future<Response_upload_order?> uploadOrderTask(
      {
        String? taskId,
        String? typeCode,
        String? fastOrderNo,
        String? pushJson,
        String? pushVersion,
        String? pushClient
      }
      ) async{
    //
    String url = "${getXServerUrl2()}/retail-order-front/fast/order/task/push";
    //
    Request_upload_order request=Request_upload_order(
        taskId: taskId,
        typeCode: typeCode,
        fastOrderNo: fastOrderNo,
        pushJson: pushJson,
        pushVersion: pushVersion,
        pushClient: pushClient
    );
    //
    Map<String,dynamic>? responseMap= await requestApi_sync(
        url:url,
        requestJson:XJsonUtils.obj2Json(request)
    );

    if(responseMap!=null){
      Response_upload_order response=Response_upload_order.fromJson(responseMap);
      return response;
    }

    return null;

  }

  //上传任务2.0
  static Future<Response_upload_order?> uploadOrderTask2(
      {
        required Map<String,dynamic> request
      }
      ) async{
    //
    String url = "${getXServerUrl2()}/retail-order-front/fast/order/task/push/comb";
    //
    String tokenId=XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    request['tokenId']=tokenId;

    //
    Map<String,dynamic>? responseMap= await requestApi_sync(
        url:url,
        requestJson:XJsonUtils.obj2Json(request)
    );

    if(responseMap!=null){
      Response_upload_order response=Response_upload_order.fromJson(responseMap);
      return response;
    }

    return null;

  }


  static void downloadDBFileWaitH5CallbackFileUrl(
      {
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/product-task/offlinePos/downloadOfflineProducts";
    //
    RequestDownloadDbFileUrl request=RequestDownloadDbFileUrl();
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }

  static void h5RequestApiCommon(
      {
        required String url,
        required String json,
        required String key,
        required RBApiCallbackSucceedT<String> succeed,
      }
      ){
    requestApi_async(
        url:url,
        requestJson:json,
        failed:(String code,String msg){
          //不用失败情况,也不用通知h5
        },
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed('',responseMap,headersResponse);
        }
    );

  }


  //上传更新serverSocket ip
  static void updateServerSocketInfo(
      {
        required List<BeanSocketPrintSetDTOS> printSetDTOS,
        required RBApiCallbackSucceedT<RBBaseResponse> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-order-front/printSet/save";
    //
    RequestUpdateServerSocket request=RequestUpdateServerSocket(printSetDTOS);
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          RBBaseResponse response=RBBaseResponse.fromJson(responseMap);
          succeed(response,responseMap,headersResponse);
        }
    );

  }

  //获得serverSocket ip
  static void getServerIPList(
      {
        required RBApiCallbackSucceedT<ResponseGetServerIPList> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-order-front/printSet/info";
    //
    RequestGetServerIPList request=RequestGetServerIPList(XSharePreferencesUtils.getString(RBConfigs.SP_companyId));
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          ResponseGetServerIPList response=ResponseGetServerIPList.fromJson(responseMap);
          succeed(response,responseMap,headersResponse);

        }
    );

  }

/*
     增量更新商品数据
     */
  static Future<Response_updateGoodItemsDB?> updateGoodItemsDB(
      {
        required List<String> itemIds,
      }
      ) async{
    //
    String url = "${getXServerUrl2()}/product-task/offlinePos/downloadSpecifyOfflineProducts";
    //
    Request_updateGoodItemDB request=Request_updateGoodItemDB();
    request.itemIds=itemIds;
    //
    Map<String,dynamic>? responseMap= await requestApi_sync(
        url:url,
        requestJson:XJsonUtils.obj2Json(request)
    );

    if(responseMap!=null){
      Response_updateGoodItemsDB response=Response_updateGoodItemsDB.fromJson(responseMap);
      return response;
    }

    return null;

  }

  //增量促销(单个)
  static void checkPromotion1(
      {
        required String projectId,
        required RBApiCallbackSucceedT<Response_websocket_promotion> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-shoppingcart-task/promotion/data/project/getDownloadUrl";
    //
    Request_websocket_promotion request=Request_websocket_promotion(projectId:projectId);
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          Response_websocket_promotion response=Response_websocket_promotion.fromJson(responseMap);
          succeed(response,responseMap,headersResponse);
        }
    );

  }
  //增量促销(门店,品牌)
  static void checkPromotion2(
      {
        required RBApiCallbackSucceedT<Response_websocket_promotion> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-shoppingcart-task/promotion/data/comp/getDownloadUrl";
    //
    RBBaseRequest request=RBBaseRequest();
    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          Response_websocket_promotion response=Response_websocket_promotion.fromJson(responseMap);
          succeed(response,responseMap,headersResponse);
        }
    );

  }
  //获得服务端时间
  static void getServerTime(
      {
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/retail-order-front/common/system/date";
    //
    requestApi_async(
        url:url,
        requestMap:{},
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }

  //绑定快麦云设备
  static void bindKuaimaiCloudDevice(
      {
        required String? sn,
        String? deviceKey,
        String? bindName,
        String? noteName,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/reabam-hardware-platform/kuaimai/cloud/bindDevice";
    //
    Map<String,dynamic> requestMap={};
    requestMap['sn']=sn;
    requestMap['deviceKey']=deviceKey;
    requestMap['bindName']=bindName;
    requestMap['noteName']=noteName;
    //
    requestApi_async(
        url:url,
        requestMap:requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }

  //使用快麦云设备打印 https://showdoc.reabam.com/web/#/52?page_id=8336
  static void useKuaimaiCloudDevicePrint(
      {
        required String? requestId,
        required Map<String,dynamic>? dataSet,
        required String? sn,
        required String? templateId,
        required int? type,
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/reabam-hardware-platform/kuaimai/cloud/printData";
    //
    Map<String,dynamic> requestMap={};
    requestMap['requestId']=requestId;
    requestMap['dataSet']=dataSet;
    requestMap['sn']=sn;
    requestMap['templateId']=templateId;
    requestMap['type']=type;
    //
    requestApi_async(
        url:url,
        disableRetry:false,
        receiveTimeout: const Duration(seconds: 5),
        requestMap:requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          succeed(null,responseMap,headersResponse);
        }
    );

  }


  static Future<ResponseBarcodeRule?> getBarcodeSearchRule() async{
    //
    String url = "${getXServerUrl2()}/config/barcodeSearchRule/getList";
    //
    RBBaseRequest request=RBBaseRequest();
    //
    Map<String,dynamic>? responseMap= await requestApi_sync(
        url:url,
        requestJson:XJsonUtils.obj2Json(request)
    );

    //XLogUtils.printLog('---getBarcodeSearchRule=$responseMap',tag: 'tess');
    if(responseMap!=null){
      ResponseBarcodeRule response=ResponseBarcodeRule.fromJson(responseMap);
      return response;
    }

    return null;

  }


  //又拍云参数
  static void getYoupaiyunConfig(
      {
        required RBApiCallbackSucceedT<dynamic> succeed,
        required XHttpCallbackFailed failed,
      }
      ){
    //
    String url = "${getXServerUrl2()}/core/app/Common/GetUpyunFormParams";
    //
    Map<String,dynamic> requestMap={};
    requestMap['uploadType']='other';

    //
    requestApi_async(
        url:url,
        requestMap:requestMap,
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headers_response){
          succeed(null,responseMap,headers_response);
        }
    );

  }



  //保存文件上传记录
  static void saveUpYunInfo({
    required Map<String, dynamic> file_youpaiyun,//又拍云
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {

    Map<String, dynamic> fileMap = {};
    fileMap['fileName'] = (file_youpaiyun['url'] as String).substring((file_youpaiyun['url'] as String).lastIndexOf('/'));
    fileMap['fileOrgName'] = (file_youpaiyun['url'] as String).substring((file_youpaiyun['url'] as String).lastIndexOf('/') + 1);
    fileMap['fileSize'] = file_youpaiyun['file_size'];
    fileMap['fileUrl'] = file_youpaiyun['url'];
    fileMap['fileFullUrl'] = file_youpaiyun['fileFullUrl'];

    //
    String url = "${getXServerUrl2()}/core/app/Common/Attachment/Add";

    Map<String,dynamic> requestMap={};
    List<dynamic> files=[];
    files.add(fileMap);
    requestMap['files']=files;
    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap, Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }


  //上传设备设置记录
  static void uploadDeviceSettingInfo(
      bool isLogIn,//是否登录时上传,
      ){
    //https://showdoc.reabam.com/web/#/8?page_id=7394
    String url = "${getXServerUrl2()}/retail-order-front/pos/machine/add";

    //
    RequestUploadDeviceSettingInfo request=RequestUploadDeviceSettingInfo();
    request.logIn=isLogIn;

    request.lastReportingTime=XDateUtils.getCurrentTime_String(format:XDateUtils.formatTimeDefault1);
    request.companyId=XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    request.companyCode=XSharePreferencesUtils.getString(RBConfigs.SP_companyCode);
    request.companyName=XSharePreferencesUtils.getString(RBConfigs.SP_companyName);

    //设备号
    String deviceNo=XSharePreferencesUtils.getString("machineCode${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}");
    request.machineNo=deviceNo.replaceAll('"', deviceNo);

    if(XStringUtils.isEmpty(request.machineNo)){
      XLogUtils.printLog('---设备号为空,不上传设备设置记录');
      return;
    }

    request.status="1";

    //切换本地打印
    request.switchLocalPrint=false;
    //本机接单打印
    request.localPrint=XSharePreferencesUtils.getBool('getIsReceiveTakeawayInfo${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',defaultValue:false);
    //启用扫码盒扫码
    request.scanCodeBoxPrint=XSharePreferencesUtils.getBool('getIsUseScanBox${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',defaultValue:false);
    //极速收银
    request.speedCash=XSharePreferencesUtils.getBool('getIsQuickCash${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',defaultValue:true);
    //商品缓存
    request.productCache=XSharePreferencesUtils.getBool('getIsGoodsCache${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',defaultValue:true);


    //取餐码/餐牌号: {"preCode":"S","startNum":"0001","endNum":"9999","nowNum":"0001"}
    //test
    String jsonCmpMealcode=XSharePreferencesUtils.getString("cmp_mealCode${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}");
    //L.sdk("--json_cmp_mealCode="+json_cmp_mealCode);
    Map<String,dynamic> mapCmpMealcode=XJsonUtils.json2Map(jsonCmpMealcode);
    request.mealTakeCodePrefix=mapCmpMealcode['preCode'];
    request.mealTakeCodeStart=mapCmpMealcode['startNum'];
    request.mealTakeCodeEnd=mapCmpMealcode['endNum'];
    request.mealTakeCodeNum=mapCmpMealcode['nowNum'];

    //打印机
    List<PosMachinePrintersBean> posMachinePrinters=[];


    XBaseDevice? socketTv;
    Set<XBaseDevice> connectedDeviceList=XSocketUtils.socketDeviceList;
    XLogUtils.printLog('---socket size=${connectedDeviceList.length}');
    for(XBaseDevice item in connectedDeviceList){
      if(RBConfigs.SocketTV==item.customType){
        socketTv=item;
      }else if(RBConfigs.IPPrinter==item.customType){


        PosMachinePrintersBean iitem= PosMachinePrintersBean();
        //打印机类型：0-网络、 1-USB、 2-蓝牙
        iitem.printerType="0";
        iitem.printerName=item.deviceName;
        iitem.ip=item.ip;
        iitem.lineNo=item.serialNumber;

        List<XBaseDeviceScene>? scenes=item.scenes;
        StringBuffer sb= StringBuffer();
        if (scenes!=null){
          for (int j=0;j<scenes.length;j++){
            if (j==scenes.length-1){
              sb.write(scenes[j].name);
            }else{
              sb.write("${scenes[j].name},");
            }
          }
        }
        String tagStr=sb.toString();
        if (XStringUtils.isEmpty(tagStr)){
          tagStr="无";
        }
        iitem.scene=tagStr;
        //
        posMachinePrinters.add(iitem);
      }
    }

    //叫号屏ip地址
    if(socketTv!=null){
      request.queueNumberBoardIp=socketTv.ip;
      request.queueNumberBoardStatus=socketTv.isConnected;
    }


    //usb打印
    Set<XBaseDevice> usbDeviceList=XUsbUtils.usbDeviceList;
    for(XBaseDevice item in usbDeviceList){
      if(RBConfigs.USBPrinter==item.customType){

        PosMachinePrintersBean iitem=PosMachinePrintersBean();
        //打印机类型：0-网络、 1-USB、 2-蓝牙
        iitem.printerType="1";
        iitem.printerName=item.deviceName;
        iitem.printerId=item.deviceUUID;
        iitem.lineNo=item.serialNumber;

        List<XBaseDeviceScene>? scenes=item.scenes;
        StringBuffer sb= StringBuffer();
        if (scenes!=null){
          for (int j=0;j<scenes.length;j++){
            if (j==scenes.length-1){
              sb.write(scenes[j].name);
            }else{
              sb.write("${scenes[j].name},");
            }
          }
        }
        String tagStr=sb.toString();
        if (XStringUtils.isEmpty(tagStr)){
          tagStr="无";
        }
        iitem.scene=tagStr;
        //
        posMachinePrinters.add(iitem);

      }
    }


    //蓝牙
    XBaseDevice? weigherBluetooth;
    Set<XBaseDevice> bluetoothBLEDeviceList=XBluetoothBLEUtils.bluetoothBLEDeviceList;
    for(XBaseDevice item in bluetoothBLEDeviceList){
      if(RBConfigs.BluetoothPrinter==item.customType){

        PosMachinePrintersBean iitem=PosMachinePrintersBean();
        //打印机类型：0-网络、 1-USB、 2-蓝牙
        iitem.printerType="2";
        iitem.printerName=item.deviceName;
        iitem.printerId=item.bluetoothAddress;
        iitem.lineNo=item.serialNumber;

        List<XBaseDeviceScene>? scenes=item.scenes;
        StringBuffer sb= StringBuffer();
        if (scenes!=null){
          for (int j=0;j<scenes.length;j++){
            if (j==scenes.length-1){
              sb.write(scenes[j].name);
            }else{
              sb.write("${scenes[j].name},");
            }
          }
        }
        String tagStr=sb.toString();
        if (XStringUtils.isEmpty(tagStr)){
          tagStr="无";
        }
        iitem.scene=tagStr;
        //
        posMachinePrinters.add(iitem);

      }else if(RBConfigs.BluetoothWeigher==item.customType){
        weigherBluetooth=item;
      }
    }

    //蓝牙电子秤名称
    if (weigherBluetooth!=null){
      request.bluetoothScaleName=weigherBluetooth.deviceName;
    }

    //远程打印机(快麦云打印)
    Set<XBaseDevice> kuaimaiCloudDeviceList=XRemoteDeviceUtils.remoteDeviceList;
    for(XBaseDevice item in kuaimaiCloudDeviceList){
      PosMachinePrintersBean iitem=PosMachinePrintersBean();
      //打印机类型：0-网络、 1-USB、 2-蓝牙  3-云打印
      iitem.printerType="3";
      iitem.printerName=item.deviceName;
      iitem.printerId=item.deviceUUID;
      iitem.lineNo=item.serialNumber;

      List<XBaseDeviceScene>? scenes=item.scenes;
      StringBuffer sb= StringBuffer();
      if (scenes!=null){
        for (int j=0;j<scenes.length;j++){
          if (j==scenes.length-1){
            sb.write(scenes[j].name);
          }else{
            sb.write("${scenes[j].name},");
          }
        }
      }
      String tagStr=sb.toString();
      if (XStringUtils.isEmpty(tagStr)){
        tagStr="无";
      }
      iitem.scene=tagStr;
      //
      posMachinePrinters.add(iitem);
    }

    //打印机
    request.posMachinePrinters=posMachinePrinters;


    //
    requestApi_async(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:(String code,String msg){
          //
        },
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          //
        }
    );

  }


  //快麦打印//////////////////////////////////////////////////////////////////////////

  //测试域名
  //String _kmUrl="http://label-component-test.kuaimai.com";
  //正式域名
  static const String _kmUrl="http://label-component.kuaimai.com";

  static const String _kmAppId="1625638525787";
  static const String _kmAppSecret="dabef9624c4d4a318cd9843584c2ef1c";

  //快麦api签名
  static void _setKuaimaiSign(BaseKMRequest request) {
    String timestamp = XDateUtils.getCurrentTime_String(format: XDateUtils.formatTimeDefault2);
    String randomNum = '${XNumberUtils.randomInt(12345678) + 200000000}';
    String x = '$_kmAppSecret$_kmAppId$timestamp$randomNum$_kmAppSecret';
    String sign = XJiamiUtils.strToMd5(x).toLowerCase();
    request.appId = _kmAppId;
    request.timestamp = timestamp;
    request.randomNum = randomNum;
    request.sign = sign;
  }

  //小票打印命令获取
  static void kmXiaopiaoPrint(
      {
        required String templateId,
        required String renderData,
        required String requestId,
        required RBApiCallbackSucceedT succeed,
        required XHttpCallbackFailed failed
      }
      ) {

    //
    String url = "$_kmUrl/api/label/component/getEscInstruct";
    //
    Request_km_xiaopiao request = Request_km_xiaopiao(
        templateId: templateId,
        renderData: renderData,
        requestId: requestId
    );
    _setKuaimaiSign(request);

    //
    requestApi_km(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          //Response_km_xiaopiao response=Response_km_xiaopiao.fromJson(responseMap);
          succeed(null,responseMap,headersResponse);
        }
    );

  }

  //tspl标签打印
  static void kmTSPLPrint(
      {
        required String templateId,
        required String renderData,
        required String requestId,
        required RBApiCallbackSucceedT succeed,
        required XHttpCallbackFailed failed
      }
      ) {

    //
    String url = "$_kmUrl/api/label/component/getTsplInstruct";
    //
    Request_km_biaoqian request = Request_km_biaoqian(
      templateId: templateId,
      renderData: renderData,
      requestId: requestId,
    );
    _setKuaimaiSign(request);

    //
    requestApi_km(
        url:url,
        requestJson:XJsonUtils.obj2Json(request),
        failed:failed,
        succeed: (Map<String,dynamic> responseMap,Map<String,dynamic> headersResponse){
          //Response_km_xiaopiao response=Response_km_xiaopiao.fromJson(responseMap);
          succeed(null,responseMap,headersResponse);
        }
    );

  }

// public void kmXiaopiaoPrintPreview(Context context,
//     String templateId,
//     String renderData,
//     String requestId,
//     final XResponseListener2<Response_km_xiaopiaoPreview> listener) {
//
//   String url = kmUrl + "/api/label/component/getEscInstructImage";
//
//   Request_km_xiaopiao request = new Request_km_xiaopiao();
//   setKuaimaiSign(request);
//
//   request.templateId = templateId;
//   request.renderData = renderData;
//   request.requestId = requestId;
//
//   requestJsonByOkHttpPost_km(
//       context,
//       api.getAndroid_UUID(),
//       url,
//       request,
//       new HandlerResponse_CallBack_km<Response_km_xiaopiaoPreview>(context, Response_km_xiaopiaoPreview.class) {
//   @Override
//   public void failed(String s, String s1) {
//   listener.failed(s, s1);
//   }
//
//   @Override
//   public void succeed(Response_km_xiaopiaoPreview response, Map<String, String> headerMap) {
//   listener.succeed(response, headerMap);
//   }
//   });
// }

  //单张识别 https://showdoc.reabam.com/web/#/54?page_id=8522
  static void aiRecognitionImage({
    required String file, //base64
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {

    //
    String url = "${getXServerUrl2()}/reabam-ai/ai/recognition/single/img";

    Map<String, dynamic> requestMap = {};
    requestMap['file']=file;
    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap, Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }


  ///////////////////////////////////////////////////////////////////////////////

  //初始化阿里云日志
  static void initAliyunLog(String appName){

    String endpoint;
    String project;
    String logstore;
    String accesskeyid;
    String accesskeysecret;

    if(RBConfigs.versionType==VersionType.testVersion
        || RBConfigs.versionType==VersionType.developerVersion
    ){
      //测试版
      endpoint='https://cn-shenzhen.log.aliyuncs.com';
      project='reabam-app-log';
      logstore='pos_app_android_test';
      accesskeyid='LTAI5t6gtXxdKepYHRymyFTX';
      accesskeysecret='wwrc7roPwIlAzYGMLSNfhhDn7nkyWL';

    }else{

      //正式版
      endpoint='https://cn-shenzhen.log.aliyuncs.com';
      project='reabam-app-log';
      logstore='pos_app_android_prod';
      accesskeyid='LTAI5t6gtXxdKepYHRymyFTX';
      accesskeysecret='wwrc7roPwIlAzYGMLSNfhhDn7nkyWL';
    }

    //
    String deviceNo=XSharePreferencesUtils.getString('machineCode${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}');

    Map<String,dynamic> customTags={};
    customTags['companyId']=XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    customTags['companyName']=XSharePreferencesUtils.getString(RBConfigs.SP_companyName);
    customTags['userCode']=XSharePreferencesUtils.getString(RBConfigs.SP_userCode);
    customTags['userName']='${XSharePreferencesUtils.getString(RBConfigs.SP_userName)}, userId=${XSharePreferencesUtils.getString(RBConfigs.SP_userId)}, tokenId=${XSharePreferencesUtils.getString(RBConfigs.SP_tokenId)}';
    customTags['设备号']=deviceNo;
    customTags['设备信息']=XJsonUtils.obj2Json(XTempData.deviceInfo);


    //睿本云HD
    XAliyunLogUtils.init(
      appName: '${appName}_${RBConfigs.versionName}',
      endpoint: endpoint,
      project: project,
      logstore: logstore,
      accessKeyID: accesskeyid,
      accessKeySecret: accesskeysecret,
      customTags: customTags,
    );
  }

  //重新获取支付方式和商品分类
  static void initGetPayTypeAndGoodType(){

    String companyId=XSharePreferencesUtils.getString(RBConfigs.SP_companyId);

    XLogUtils.printLog('---1.重新获取商品分类');
    RBBaseApi.goodTypeList(
        optType:'2',
        filterType: 'Order',
        failed: (String code,String msg){
          XLogUtils.printLog('---重新获取商品分类失败: code:$code,msg=$msg');
        },
        succeed: (GoodTypeResponse response, Map<String,dynamic> responseMap,Map<String, dynamic> headersResponse) async {
          //保存商品分类
          dynamic DataLine=responseMap['DataLine'];
          String pTypeJson=XJsonUtils.obj2Json(DataLine);
          XSharePreferencesUtils.saveString('${RBConfigs.SP_Pos_OfflineDB_goodsType}$companyId',pTypeJson);
          XLogUtils.printLog('---重新获取商品分类pTypeJson=$pTypeJson');
        }
    );

    //下载支付方式
    XLogUtils.printLog('---2.重新获取下载商品分类');
    RBBaseApi.payList(
      equipmentIdentity:RBConfigs.isShangMiDevice?"sumipay":null,
      failed: (String code, String msg) {
        XLogUtils.printLog('---重新获取下载商品分类失败: code:$code,msg=$msg');
      },
      succeed: (PayTypeResponse response, Map<String, dynamic> responseMap1, Map<String, dynamic> headersResponse) {
        //
        dynamic DataLine1=responseMap1['DataLine'];
        //保存支付方式
        XSharePreferencesUtils.saveString(RBConfigs.SP_Pos_OfflineDB_payType+companyId, XJsonUtils.obj2Json(DataLine1));
      },
    );


  }
}